package test.temple;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;

import com.weight.common.enums.ResultEnum;
import com.weight.common.exception.CSException;
import com.weight.common.generate.base.CommonUtil;
import com.weight.common.generate.base.FieldTypeEnum;
import com.weight.common.generate.base.JavaFile;
import com.weight.common.model.PageResult;
import com.weight.common.util.CommonUtils;
import com.weight.common.util.DateFormUtils;
import com.weight.common.util.JsonResultUtil;
import com.weight.system.project.PO.ProjectInfo;
import com.weight.system.project.VO.ProjectInfoVO; 


/**
* 	Controller代码生成
*/
public class ControllerClassFileMapperNew extends JavaFile {
	private String model;
	private String modelVO;
	public ControllerClassFileMapperNew(String filePath, String mainPackage, String curPackage, String packageName,String model,
			String tableCnName,String tableId,List<String> fieldENList,List<String> fieldTypeList) {
		super(filePath, getClassName(model).append(".java").toString(), mainPackage+"."+curPackage, CLASS_TYPE, 
				getClassName(model).toString());
		this.model = model;
		this.modelVO = new StringBuilder().append(model).append("VO").toString();
		
		StringBuilder beanName=getModelClass(model);
		StringBuilder beanNameVO=getModelClass(modelVO);
		
		List<String> imports = new LinkedList<String>();
		List<String> classAnnotations = new LinkedList<String>();
		List<String> extendss = new LinkedList<String>();
		List<String> importPackagePaths = new LinkedList<String>();
		List<JavaFile.Field> fieldLists = new LinkedList<Field>();
		List<Method> methodLists = new LinkedList<Method>();
		
		//imports
		imports.add(getImportName(mainPackage, model).toString());
		imports.add(getImportName(mainPackage,"VO" ,model).append("VO").toString());
		imports.add(new StringBuilder().append(mainPackage).append(".").append("service").append(".")
									   .append(beanName).append("Service").toString());
		
//		imports.add(new StringBuilder().append(mainPackage).append(".util.Result").toString());
		
		imports.add("java.util.HashMap");
		imports.add("java.util.List");
		imports.add("java.util.Map");
		imports.add("java.util.stream.Collectors");
		
		imports.add("javax.servlet.http.HttpServletRequest");
		imports.add("javax.validation.Valid");
		imports.add("org.springframework.beans.BeanUtils");
		imports.add("org.apache.commons.lang3.StringUtils");
		imports.add("org.springframework.beans.factory.annotation.Autowired");
		imports.add("org.springframework.web.bind.annotation.RestController");
		imports.add("org.springframework.web.bind.annotation.RequestMapping");
		imports.add("org.springframework.web.bind.annotation.RequestMethod");
		imports.add("org.springframework.web.bind.annotation.RequestParam");
		imports.add("org.springframework.transaction.annotation.Transactional");
		imports.add("org.springframework.web.servlet.ModelAndView");
		
		imports.add("com.alibaba.fastjson.JSON");
		
//		imports.add("org.springframework.ui.Model");
		imports.add("com.weight.common.util.JsonResultUtil");
		imports.add("com.weight.common.util.CommonUtils");
		imports.add("com.weight.common.util.DateFormUtils");
		imports.add("com.weight.common.model.PageResult");
		imports.add("lombok.extern.slf4j.Slf4j");
		imports.add("org.springframework.validation.BindingResult");
	 
		imports.add("com.weight.common.enums.ResultEnum");
//		imports.add("com.weight.common.exception.CSException");
		
		//classAnnotations
		classAnnotations.add("RestController");
		classAnnotations.add("Slf4j");
		
		classAnnotations.add(new StringBuilder().append("RequestMapping(\"/").append(packageName).append("/").append(model)
				.append("\")").toString());
		
		//fieldLists
		List<String> fannotations = new LinkedList<String>();
 
		fannotations = new LinkedList<String>();
		fannotations.add("Autowired");
		String fmodifier = "private";
		String ftype = new StringBuilder().append(beanName).append("Service").toString();
		String serviceName = new StringBuilder().append(model).append("Service").toString();
		String value = null;
		Field field = new Field(fannotations, fmodifier , ftype, serviceName, value);
		fieldLists.add(field);
		
		fannotations = new LinkedList<String>();
		field = new Field(fannotations, "private" , "String", "pattern", "\"yyyy-MM-dd\"");
		fieldLists.add(field);
		
		List<String>argLists=null;//方法 入参別名
		Collection<String> descriptionList=null;//方法描述注释
		//methodLists
		String description=null;
		List<String> mannotations = new LinkedList<String>();
		String mmodifier = "public";
		String resultType = "ModelAndView";
		String methodName;
		String args;
		List<String> exceptions = null;
		String methodBody = null;
		
//1.查询项目基本信息列表页GET     	 
		methodName = new StringBuilder().append("queryFor").append(beanName).append("List").toString();
		mannotations.add(new StringBuilder().append("RequestMapping(value=\"/").append(methodName)
											.append("\",method=RequestMethod.GET)").toString());
		args = null;
		argLists=new ArrayList<String>();	
		descriptionList=CommonUtil.descriptionModel(new StringBuilder("1.查询").append(tableCnName).append("--列表页 "),argLists,true);
		methodBody = buildMethod2(new String[] {
				"Map<Object, Object> map =new HashMap<>();",
				"map.put(\"status\", 1);\n" + 
				"			\n" + 
				"			//2、查询"+tableCnName+"列表\n" + 
				"			List<"+beanName+"> "+model+"List = "+serviceName+".find"+beanName+"ByT(map);\n" ,
				new StringBuilder("log.info(\"").append(model).append("List={}\",").append(model).append("List);").toString(),
				new StringBuilder("List<").append(beanNameVO).append("> ").append(modelVO).append("List = ").append(model)
				.append("List.stream().map(e -> changePoToVO(e)).collect(Collectors.toList());").toString(),				
 
				"			\n" + 
				"			//3、返回前台\n" + 
				"			ModelAndView modelAndView = new ModelAndView();\n" + 
				"			modelAndView.setViewName(\""+model+"/queryFor"+beanName+"List\");\n" + 
				"			modelAndView.addObject(\""+model+"VOList\","+model+"VOList);",
				"return modelAndView;"
		});
		 				
	
//	 (String filePath, String mainPackage, String curPackage, String packageName,String model,
//	String tableCnName,String tableId,List<String> fieldENList,List<String> fieldTypeList) {
		
		
		Method method = new Method(descriptionList,mannotations, mmodifier, resultType, methodName, args, exceptions, methodBody);
		methodLists.add(method);
		
			 
		StringBuilder requestStr=new StringBuilder();
		StringBuilder mapStr=new StringBuilder();
		for(int i=1;i<fieldENList.size();i++) {
			if(i>1) {
				requestStr.append("\t\t\t");
				mapStr.append("\t\t\t");
			}
			requestStr.append("String ").append(fieldENList.get(i)).append(" = request.getParameter(\"").append(fieldENList.get(i)).append( "\");\n");
			
			ftype=FieldTypeEnum.fromResultEnumPo(fieldTypeList.get(i).toUpperCase());
			if(ftype.equals("Date")) {
				mapStr.append("map.put(\"").append(fieldENList.get(i)).append("\", DateFormUtils.getStringToDate(").append(fieldENList.get(i)).append(", pattern));\n");
			}else {
				mapStr.append("map.put(\"").append(fieldENList.get(i)).append("\", ").append(fieldENList.get(i)).append(");\n");
			}
			
		}
		
		

		//4.添加、修改项目基本信息操作
				resultType = "ModelAndView";
				methodName = new StringBuilder().append("add").append(beanName).toString();
				mannotations = new LinkedList<String>();
				mannotations.add(new StringBuilder().append("RequestMapping(value=\"/").append(methodName).append("\")").toString());
				args = new StringBuilder().append("@RequestParam(value=\"").append(tableId).append("\",required=false) String ")
										  .append(tableId).toString();
				argLists=new ArrayList<String>();	
				argLists.add(tableId);
				descriptionList=CommonUtil.descriptionModel(new StringBuilder("3.添加、修改").append(tableCnName).append("操作"),argLists,true);
				
				methodBody = buildMethod2(new String[] {
						"//1、创建返回对象",
						new StringBuilder().append(beanNameVO).append(" ").append(modelVO).append(" = new ")
										   .append(beanNameVO).append("();").toString(),
						"",
						"//2.判定id不为空，则查询数据库，为修改操作",
						new StringBuilder().append("if(StringUtils.isNotBlank(").append(tableId).append(")) {").toString(),
						"\tMap<String, String> map=new HashMap<>();",
						new StringBuilder().append("\tmap.put(\"").append(tableId).append("\", ").append(tableId).append(");").toString(),
						new StringBuilder().append("\tlog.info(\"修改操作，查询ID：").append(tableId).append("={}\",").append(tableId).append(");").toString(),
						new StringBuilder().append("\t").append(beanName).append(" ").append(model).append( " = ")
										   .append(serviceName).append(".findBy").append(beanName).append("Id(map);").toString(),
//						new StringBuilder().append("\tBeanUtils.copyProperties(").append(model).append(",").append(modelVO)
//										   .append( ");").toString(),
										   
						new StringBuilder().append("\tthis.changePoToVO(").append(modelVO).append(",").append(model)
										   .append( ");").toString(),				   
										   
						"}",
						"",
						"//3.数据返回给前台",
						"ModelAndView modelAndView = new ModelAndView();",
						new StringBuilder().append("modelAndView.setViewName(\"/system/").append(packageName).append("/add")
										   .append(beanName).append("\");").toString(),
						new StringBuilder().append("modelAndView.addObject(\"").append(modelVO).append("\",").append(modelVO)
										   .append(");").toString(),
						"modelAndView.addObject(\"formID\",CommonUtils.getUUId());",
						"return modelAndView;"
				});
				method = new Method(descriptionList,mannotations, mmodifier, resultType, methodName, args, exceptions, methodBody);
				methodLists.add(method);		

				
				

				
				
				//5.保存 添加、修改项目基本信息操作
						resultType = "JsonResultUtil";
						methodName = new StringBuilder().append("save").append(beanName).toString();
						mannotations = new LinkedList<String>();
						mannotations.add("Transactional");
						mannotations.add(new StringBuilder().append("RequestMapping(value=\"/").append(methodName).append("\")").toString());
						args = new StringBuilder().append("@Valid ").append(beanNameVO).append(" ").append(modelVO)
												  .append(",BindingResult bindingResult").toString();
						argLists=new ArrayList<String>();	
						argLists.add(modelVO);
						argLists.add("bindingResult");
						descriptionList=CommonUtil.descriptionModel(new StringBuilder("5.保存 添加、修改").append(tableCnName).append("操作"),argLists,true);
						methodBody = buildMethod2(new String[] {
								"String operateStr=\"add\";",
								"//1.校验入参规则",
								new StringBuilder().append("CommonUtils.validateBindingResult(bindingResult,").append(modelVO).append(");").toString(),
								"",
								"//2.获取id",
								new StringBuilder().append("String ").append(tableId).append("=").append(modelVO).append(".get")
												   .append(getModelClass(tableId)).append("();").toString(),
								new StringBuilder().append(beanName).append(" ").append(model).append("=new ")
												   .append(beanName).append("();").toString(),
								new StringBuilder().append("BeanUtils.copyProperties(").append(modelVO).append(",")
												   .append(model).append( ");").toString(),
								new StringBuilder().append("this.changeVOToPO(").append(modelVO).append(",")
												   .append(model).append( ");").toString(),
								"",
								"//3.判定id不为空，则为修改操作",
								new StringBuilder().append("if(StringUtils.isNotBlank(").append(tableId).append(")) {").toString(),
								"\toperateStr=\"edit\";",
								"\tMap<String, String> map=new HashMap<>();",
								new StringBuilder().append("\tmap.put(\"").append(tableId).append("\", ").append(tableId).append(");").toString(),
								new StringBuilder().append("\tlog.info(\"修改操作，查询ID：").append(tableId).append("={}\",").append(tableId)
												   .append(");").toString(),
								"\t//查询是否存在",
								new StringBuilder().append("\t").append(serviceName).append(".findBy").append(beanName)
												   .append("Id(map);").toString(),
								"\ttry{",
								new StringBuilder().append("\t\t").append(model).append(".setUpdateBy(\"000\");").toString(),
								new StringBuilder().append("\t\t").append(serviceName).append(".update").append(beanName)
												   .append("(").append(model).append(");").toString(),
								new StringBuilder().append("\t\tlog.info(\"更新操作成功：").append(model).append("={}\",").append(model)
												   .append(");").toString(),
								"\t}catch(Exception e){",
								"\t\te.printStackTrace();",
								"\t\tlog.error(e.getMessage(), e);",
								"\t\treturn new JsonResultUtil(ResultEnum.EXCEPTION, \"失败！\", e.getMessage());",
								"\t}",
								"}else {//判定id为空，则为添加操作",
								"\ttry{",
								new StringBuilder().append("\t\t").append(model).append(".set").append(getModelClass(tableId))
												   .append("(CommonUtils.getUUId());").toString(),
								new StringBuilder().append("\t\t").append(model).append(".setCreateBy(\"000\");").toString(),
								new StringBuilder().append("\t\t").append(model).append(".setUpdateBy(\"000\");").toString(),
								new StringBuilder().append("\t\t").append(serviceName).append(".insert").append(beanName)
												   .append("(").append(model).append(");").toString(),
								new StringBuilder().append("\t\tlog.info(\"添加操作成功：").append(model).append("={}\",")
												   .append(model).append(");").toString(),
								"\t}catch(Exception e){",
								"\t\te.printStackTrace();",
								"\t\tlog.error(e.getMessage(), e);",
								"\t\treturn new JsonResultUtil(ResultEnum.EXCEPTION, \"失败！\", e.getMessage());",
								"\t}",
								"}",
								"return new JsonResultUtil(ResultEnum.SUCCESS, \"操作成功！\", operateStr);"
						});
						method = new Method(descriptionList,mannotations, mmodifier, resultType, methodName, args, exceptions, methodBody);
						methodLists.add(method);
						
				 				
		
	////////////////////////////////////////////////////////////////////	
		
		
		
		
		 
		/**	类注释	*/
		Collection<String> classDescriptionList=CommonUtil.descriptionModel(new StringBuilder(tableCnName), null, false);
		super.init(imports, classAnnotations, extendss, importPackagePaths, fieldLists, methodLists,classDescriptionList);
	}
	 
	public static StringBuilder getClassName(String model) {
		StringBuilder className = new StringBuilder();
		className.append(getModelClass(model));
		className.append("Controller");
		return className;
	}

	private static String buildMethod(String[] lines) {
		StringBuilder method = new StringBuilder();
		method
		.append("\t\t")
		.append("try{")
		.append("\n");
		if(lines != null) {
			for (String line : lines) {
				method
				.append("\t\t\t")
				.append(line)
				.append("\n");
			}
		}
		method
		.append("\t\t")
		.append("}catch(Exception e){")
		.append("\n")
		.append("\t\t\t")
		.append("e.printStackTrace();")
		.append("\n")
		.append("\t\t\t")
		.append("log.error(e.getMessage(), e);")
		.append("\n")
		.append("\t\t\t")
		.append("return new JsonResultUtil(ResultEnum.EXCEPTION, \"失败！\", e.getMessage());")
//		.append("return Result.failure(e.toString());")
		.append("\n")
		.append("\t\t")
		.append("}")
		.append("\n")
		.toString();
		return method.toString();
	}
	private static String buildMethod2(String[] lines) {
		StringBuilder method = new StringBuilder();
		if(lines != null) {
			for (String line : lines) {
				method.append("\t\t\t")
					 .append(line)
					.append("\n");
			}
		}
		return method.toString();
	}
}
